# server.proxy

- **Type:**

```ts
type ProxyConfig =
  | Record<string, string | ProxyOptions>
  | ProxyOptions[]
  | ProxyOptions;
```

- **Default:** `undefined`

Configure proxy rules for the dev server or preview server to proxy requests to the specified service.

## Example

### Basic usage

```ts title="rsbuild.config.ts"
export default {
  server: {
    proxy: {
      // http://localhost:3000/api -> http://localhost:3000/api
      // http://localhost:3000/api/foo -> http://localhost:3000/api/foo
      '/api': 'http://localhost:3000',
    },
  },
};
```

A request to `/api/users` will now proxy the request to `http://localhost:3000/api/users`.

You can also proxy to an online domain name, such as:

```ts title="rsbuild.config.ts"
export default {
  server: {
    proxy: {
      // http://localhost:3000/api -> https://nodejs.org/api
      // http://localhost:3000/api/foo -> https://nodejs.org/api/foo
      '/api': 'https://nodejs.org',
    },
  },
};
```

### Path rewrite

If you do not want `/api` to be passed along, we need to rewrite the path:

```ts title="rsbuild.config.ts"
export default {
  server: {
    proxy: {
      // http://localhost:3000/api -> http://localhost:3000
      // http://localhost:3000/api/foo -> http://localhost:3000/foo
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
      },
    },
  },
};
```

### Proxy WebSocket

To proxy WebSocket requests, set `ws` to `true`:

```ts title="rsbuild.config.ts"
export default {
  server: {
    proxy: {
      '/rsbuild-hmr': {
        target: 'http://localhost:3000', // will proxy to ws://localhost:3000/rsbuild-hmr
        ws: true,
      },
    },
  },
};
```

## Options

The Rsbuild server proxy uses the [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware/tree/2.x) package. Check out its documentation for more advanced usage.

The full type definition of Rsbuild server proxy is:

```ts
import type { Options as HttpProxyOptions } from 'http-proxy-middleware';

type Filter = string | string[] | ((pathname: string, req: Request) => boolean);

type ProxyOptions = HttpProxyOptions & {
  bypass?: (
    req: IncomingMessage,
    res: ServerResponse,
    proxyOptions: ProxyOptions,
  ) => MaybePromise<string | undefined | null | boolean>;
  context?: Filter;
};

type ProxyConfig =
  | ProxyOptions
  | ProxyOptions[]
  | Record<string, string>
  | Record<string, ProxyOptions>;
```

In addition to the `http-proxy-middleware` options, Rsbuild also supports the `bypass` and `context` options.

### bypass

Sometimes you don't want to proxy everything. You can bypass the proxy based on the return value of a `bypass` function.

In the function, you have access to the request, response, and proxy options.

- Return `null` or `undefined` to continue processing the request with proxy.
- Return `true` to continue processing the request without proxy.
- Return `false` to produce a 404 error for the request.
- Return a path to serve from, instead of continuing to proxy the request.
- Return a Promise to handle the request asynchronously.

For example, for a browser request, you want to serve an HTML page, but for an API request, you want to proxy it. You could configure it like this:

```ts title="rsbuild.config.ts"
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        bypass(req, res, proxyOptions) {
          if (req.headers.accept.indexOf('html') !== -1) {
            console.log('Skipping proxy for browser request.');
            return '/index.html';
          }
        },
      },
    },
  },
};
```

### context

Used to proxy multiple specified paths to the same target.

```ts title="rsbuild.config.ts"
export default {
  server: {
    proxy: [
      {
        context: ['/auth', '/api'],
        target: 'http://localhost:3000',
      },
    ],
  },
};
```
